#coding=utf-8
#LightCam 组播监控程序
#init by hfh 20150212

import multiprocessing,subprocess,threading
import socket,os,time,re,traceback,sys
import lc_libs
import telnetlib,base64
import pexpect


def func(this):

	#agent_hostname=this['agent_hostname']
	devicename=this['devicename']
	deviceip=this['deviceip']
	port=this['port']
	keyword=this['keyword']
	interval=this['interval']
	devicetype=this['devicetype']
	severity=this['severity']
	schedule=this['schedule']
	holiday=this['holiday']
	
	thisvalue=0
	lastvalue=0
	initflag=0
	USER="monitor"
	PASSWD="IWNmZkV4MjAwN1w="

		
	Node=agent_hostname
	AlertGroup="MultiCast"
	AlertKey=devicename+"_"+port
	Summary=""
			
	try:
  		if devicetype == 'cisco':
			ssh=pexpect.spawn('ssh monitor@%s "show ip pim interface %s count"' % (deviceip,port))
			i=ssh.expect('assword:')
			ssh.sendline(base64.decodestring(PASSWD))
			strs=ssh.read()
			#print strs
			ssh.close()
  	
			#c=ssh.SSHClient()
			#c.set_missing_host_key_policy(ssh.AutoAddPolicy())
			#c.connect(deviceip,port=22,username=USER,password=base64.decodestring(PASSWD))
			#comd="show ip pim interface %s count" % str(port)
			#stdin,stdout,stderr=c.exec_command(comd)
			#out=stdout.read()
			#print out
			#c.close()
			#resline=""
			#for line in strs.split('\n'):
			#	if str(port) in line:
			#		resline=line
			#		break
			#print resline
			values=re.findall(r" ([0-9]+/[0-9]+)",strs,re.S)[0]
			value=values.split('/')
			thisvalue=0
			if keyword=='in':
				#thisvalue=re.findall(r"([0-9]+)/",value,re.S)
				thisvalue=int(value[0])
			elif keyword=='out':
				thisvalue=int(value[1])
			#print thisvalue
			#初始化标志文件
			lastvalue=0
			try:
				alertfilename=lchome+"/alert/lc_multicast_"+devicename+"_"+port.replace("/","_")
				rf=open(alertfilename)
				lastvalue=float(rf.read().split(',')[7])
				rf.close()
			except:
				pass
			#处理程序
			value=thisvalue-lastvalue
			value=float(value)/float(interval)
			value=str("%.2f" % value)
			lastvalue=thisvalue
			line=devicename+" "+deviceip+" "+port+" "+str(value)
			line="MultiCast,"+devicename+"_"+port+","+deviceip+","+str(value)+","+time.strftime('%Y%m%d%H%M%S',time.localtime())+",ywn_monitor1,0,Error,"
			line="MultiCast,"+devicename+"_"+port+","+deviceip+",0,"+time.strftime('%Y%m%d%H%M%S',time.localtime())+",ywn_monitor1,"+str(value)+","+str(thisvalue)+","
			outputfile=open(alertfilename,"w")
			outputfile.write(line+"\n")
			outputfile.close()
			#数据入库
			#hdb.insert_historydb(Node,procname,Summary)
			#datas=[
			#	{"Node":Node,"Name":procname,"Value":Summary.decode('gbk'),"Time":int(time.time())}
			#	]
			#db.insertDatas(history_table,datas)
		elif devicetype == 'QFX3500':
			ssh=pexpect.spawn('ssh monitor@%s "show interfaces %s detail | find counters"' % (deviceip,port))
			i=ssh.expect('assword:')
			ssh.sendline(base64.decodestring(PASSWD))
			strs=ssh.read()
			ssh.close()
			resline=""
			for line in strs.split('\n'):
				if "mcast" in line:
					resline=line
					break
			if resline=="":
				print "%s:no result\n" % AlertKey
				return 0
			#resline=resline.replace('  ',' ').replace('  ',' ').replace('  ',' ').replace('  ',' ').replace('  ',' ').replace('  ',' ').replace('  ',' ').replace('  ',' ')
			resline=resline.split()
			#print resline
			value=resline[3]
			#print "%s:%s\n" % (AlertKey,value)
			#values=re.findall(r" ([0-9]+/[0-9]+)",strs,re.S)[0]
			thisvalue=float(value)
			#初始化标志文件
			lastvalue=0
			try:
				alertfilename=lchome+"/alert/lc_multicast_"+devicename+"_"+port.replace("/","_")
				rf=open(alertfilename)
				lastvalue=float(rf.read().split(',')[7])
				rf.close()
			except:
				pass
			#处理程序
			value=thisvalue-lastvalue
			value=float(value)/float(interval)
			value=str("%.2f" % value)
			lastvalue=thisvalue
			line=devicename+" "+deviceip+" "+port+" "+str(value)
			line="MultiCast,"+devicename+"_"+port+","+deviceip+","+str(value)+","+time.strftime('%Y%m%d%H%M%S',time.localtime())+",ywn_monitor1,0,Error,"
			line="MultiCast,"+devicename+"_"+port+","+deviceip+",0,"+time.strftime('%Y%m%d%H%M%S',time.localtime())+",ywn_monitor1,"+str(value)+","+str(thisvalue)+","
			outputfile=open(alertfilename,"w")
			outputfile.write(line+"\n")
			outputfile.close()
		elif devicetype == 'MX960':
			ssh=pexpect.spawn('ssh monitor@%s "show multicast statistics inet"' % deviceip)
			i=ssh.expect('assword:')
			ssh.sendline(base64.decodestring(PASSWD))
			strs=ssh.read()
			ssh.close()
			resline=""
			for lines in strs.split('Interface'):
				if str(port) in lines:
					for line in lines.split('\n'):
						if keyword == 'in' and "In packets:" in line:
							resline=re.findall(r"In packets:[ ]+([0-9]+)",line,re.S)[0]
							break
						elif keyword == 'out' and "Out packets:" in line:
							resline=re.findall(r"Out packets:[ ]+([0-9]+)",line,re.S)[0]
							break
						else:
							pass
					break
			value=resline
			#print "%s:%s\n" % (AlertKey,value)
			#values=re.findall(r" ([0-9]+/[0-9]+)",strs,re.S)[0]
			thisvalue=float(value)
			#初始化标志文件
			lastvalue=0
			try:
				alertfilename=lchome+"/alert/lc_multicast_"+devicename+"_"+port.replace("/","_")
				rf=open(alertfilename)
				lastvalue=float(rf.read().split(',')[7])
				rf.close()
			except:
				pass
			#处理程序
			value=thisvalue-lastvalue
			value=float(value)/float(interval)
			value=str("%.2f" % value)
			lastvalue=thisvalue
			line=devicename+" "+deviceip+" "+port+" "+str(value)
			line="MultiCast,"+devicename+"_"+port+","+deviceip+","+str(value)+","+time.strftime('%Y%m%d%H%M%S',time.localtime())+",ywn_monitor1,0,Error,"
			line="MultiCast,"+devicename+"_"+port+","+deviceip+",0,"+time.strftime('%Y%m%d%H%M%S',time.localtime())+",ywn_monitor1,"+str(value)+","+str(thisvalue)+","
			outputfile=open(alertfilename,"w")
			outputfile.write(line+"\n")
			outputfile.close()
			
		else:
			logdate=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())
			logfile.write(logdate+" :\n"+AlertKey+" Unknow Device Type : "+devicetype+"\n")
			logfile.flush()
		
	except Exception:
		excinfo=traceback.format_exc()
		logdate=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())
		logfile.write(logdate+" :\n"+excinfo+" "+devicename+"\n")
		logfile.flush()
		time.sleep(1)


if __name__ == "__main__":

	lchome=lc_libs.lc_getlchome()
	scname=sys.argv[0].split('.')[0]
	logfilename=lchome+'/log/'+scname+'.log'
	confname=lchome+'/conf/'+scname+'.conf'
	
	today=time.strftime('%Y%m%d',time.localtime())
	os.system("mv %s %s.%s" % (logfilename,logfilename,today))
	
	logfile=file(logfilename,'a')
	logdate=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())
	logfile.write(logdate+" Started.\n")
	logfile.flush()
	
	agent_hostname=lc_libs.lc_gethostname()
	
	try:
		#初始化数据库
		
		db=lc_libs.lc_mongodb_operater('127.0.0.1',27017)

		db.connect()
		Conn=db.getConn()
		if Conn==None:
			print "Can not Connect to the MondbDB"
			exit(0)
		
		perf_dbname='lc_perf'
		multicast_tablename='lc_multicast'
		
		perf_db=db.useDatabase(perf_dbname)
		multicast_table=db.UseCollection(perf_db,multicast_tablename)

	except Exception:
		excinfo=traceback.format_exc()
		logdate=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())
		logfile.write(logdate+" 初始化数据库失败:\n"+excinfo+"\n")
		logfile.flush()
		exit(0)

	#主程序
	MonitorList = []
	
	for lines in open(confname):
		if lines[0] == '#' or lines.split("\t")[0] not in (agent_hostname,'default'):
			continue

		line=lines.strip('\r\n').split('\t')
		dconf={}
		
		#dconf['agent_hostname']=line[0]
		dconf['devicename']=line[1]
		dconf['deviceip']=line[2]
		dconf['port']=line[3]
		dconf['keyword']=line[4]
		dconf['devicetype']=line[5]
		dconf['interval']=line[6]
		dconf['severity']=line[7]
		dconf['schedule']=line[8]
		dconf['holiday']=line[9]
	
		MonitorList.append(dconf)

	usedtime=0
	
	while True:
		time.sleep(1)
		realtime=int(time.time())
		
		logdate=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())
		holiday_state = lc_libs.lc_isholiday()
		
		threads = []
		for i in MonitorList:
			if int(i['holiday']) == 1 and holiday_state == True:
				continue
				
			time_state = lc_libs.lc_schedule(i['schedule'])
			if time_state == False:
				continue
			
			flag=realtime%int(i['interval'])
			#print flag
			if flag<=usedtime:
				#print i
				t = threading.Thread(target=func,args=(i,))
				threads.append(t)
		
		for t in threads:
			t.start()
			while True:
				#print len(threading.enumerate())
				time.sleep(0.01)
				if(len(threading.enumerate()) < 100):
					break

		#排除执行程序导致的时间差
		usedtime=int(time.time())-realtime
		#print "usedtime:%s" % usedtime
